﻿@page "/pages/identity/loginaudits"
@using CleanArchitecture.Blazor.Application.Features.LoginAudits.DTOs
@using CleanArchitecture.Blazor.Application.Features.LoginAudits.Queries.PaginationQuery
@using CleanArchitecture.Blazor.Application.Features.LoginAudits.Specifications
@using CleanArchitecture.Blazor.Application.Features.LoginAudits.Caching
@using CleanArchitecture.Blazor.Server.UI.Components.UtcToLocalTime
@using CleanArchitecture.Blazor.Server.UI.Components.Security
@using MudBlazor

@attribute [Authorize(Policy = Permissions.LoginAudits.View)]
@inject IStringLocalizer<LoginAudits> L
@inject IMediator Mediator

<PageTitle>@Title</PageTitle>

<!-- Security Risk Dashboard -->
<SecurityRiskDashboard />

<MudDataGrid T="LoginAuditDto"
             ServerData="@(ServerReload)"
             FixedHeader="true"
             FixedFooter="false"
             RowsPerPage="@_defaultPageSize"
             Style="min-height:700px"
             Loading="@_loading"
             ColumnResizeMode="ResizeMode.Column"
             Hover="true" @ref="_table">
    <ToolBarContent>
        <MudStack Row Spacing="0" Class="flex-grow-1" Justify="Justify.SpaceBetween">
            <MudStack Row AlignItems="AlignItems.Start">
                <MudIcon Icon="@Icons.Material.Filled.Security" Size="Size.Large" />
                <MudStack Spacing="0">
                    <MudText Typo="Typo.subtitle2" Class="mb-2">@Title</MudText>
                    <MudEnumSelect Style="min-width:120px" TEnum="LoginAuditListView" ValueChanged="OnChangedListView" Value="_loginAuditsQuery.ListView" Dense="true" Label="@L["List View"]">
                    </MudEnumSelect>
                </MudStack>
            </MudStack>
            <MudStack Spacing="0" AlignItems="AlignItems.End">
                <MudToolBar Dense WrapContent="true" Class="py-1 px-0">
                    <MudButton 
                               OnClick="@(() => OnRefresh())"
                               StartIcon="@Icons.Material.Outlined.Refresh">
                        @ConstantString.Refresh
                    </MudButton>
                </MudToolBar>
                <MudStack Row Spacing="1">
                    <MudSelect T="bool?" Placeholder="@L["Login Status"]" Value="@_loginAuditsQuery.Success" Clearable="true" ValueChanged="OnChangedSuccess" Style="min-width:120px" FullWidth="true">
                        <MudSelectItem T="bool?" Value="@((bool?)true)">@L["Successful"]</MudSelectItem>
                        <MudSelectItem T="bool?" Value="@((bool?)false)">@L["Failed"]</MudSelectItem>
                    </MudSelect>
                    <MudTextField T="string" Style="min-width:200px" ValueChanged="@(OnSearch)" Value="@_loginAuditsQuery.Keyword" Placeholder="@L["Search"]" Adornment="Adornment.End"
                    AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium">
                    </MudTextField>
                </MudStack>
            </MudStack>
        </MudStack>
    </ToolBarContent>
    <Columns>
        <PropertyColumn Style="width:160px" Property="x => x.LoginTimeUtc" Title="@L[_currentDto.GetMemberDescription(x => x.LoginTimeUtc)]">
            <CellTemplate>
                <UtcToLocal UTCDateTime="@context.Item.LoginTimeUtc"></UtcToLocal>
            </CellTemplate>
        </PropertyColumn>
        <PropertyColumn Style="width:120px" Property="x => x.UserName" Title="@L[_currentDto.GetMemberDescription(x => x.UserName)]" />
        <PropertyColumn Style="width:120px" Property="x => x.IpAddress" Title="@L[_currentDto.GetMemberDescription(x => x.IpAddress)]" />
        <PropertyColumn Style="width:150px" Property="x => x.Region" Title="@L[_currentDto.GetMemberDescription(x => x.Region)]">
            <CellTemplate>
                <MudText Typo="Typo.body2">@(context.Item.Region ?? "-")</MudText>
            </CellTemplate>
        </PropertyColumn>
        <PropertyColumn Style="width:100px" Property="x => x.Provider" Title="@L[_currentDto.GetMemberDescription(x => x.Provider)]">
            <CellTemplate>
                <MudChip T="string" Color="Color.Info" Size="Size.Small">@(context.Item.Provider ?? "Local")</MudChip>
            </CellTemplate>
        </PropertyColumn>
        <PropertyColumn Style="width:120px" Property="x => x.BrowserInfo" Title="@L[_currentDto.GetMemberDescription(x => x.BrowserInfo)]">
            <CellTemplate>
                <MudTooltip Text="@context.Item.BrowserInfo">
                    <MudText Typo="Typo.body2">@(GetBrowserName(context.Item.BrowserInfo))</MudText>
                </MudTooltip>
            </CellTemplate>
        </PropertyColumn>
        <PropertyColumn Style="width:100px" Property="x => x.Success" Title="@L[_currentDto.GetMemberDescription(x => x.Success)]">
            <CellTemplate>
                @if (context.Item.Success)
                {
                    <MudChip T="string" Color="Color.Success" Size="Size.Small" Icon="@Icons.Material.Filled.CheckCircle">@L["Success"]</MudChip>
                }
                else
                {
                    <MudChip T="string" Color="Color.Error" Size="Size.Small" Icon="@Icons.Material.Filled.Error">@L["Failed"]</MudChip>
                }
            </CellTemplate>
        </PropertyColumn>
    </Columns>
    <NoRecordsContent>
        <MudText>@L["No login audit records found"]</MudText>
    </NoRecordsContent>
    <LoadingContent>
        <MudText>@ConstantString.Loading</MudText>
    </LoadingContent>
    <PagerContent>
        <MudDataGridPager PageSizeOptions="@(new[] { 10, 15, 30, 50, 100, 500, 1000 })" />
    </PagerContent>
</MudDataGrid>

@code {
    [CascadingParameter] private Task<AuthenticationState> AuthState { get; set; } = default!;
    [CascadingParameter] private UserProfile? UserProfile { get; set; }
    private string Title { get; set; } = "Login History";
    private MudDataGrid<LoginAuditDto> _table = default!;
    private readonly LoginAuditDto _currentDto = new();
    private readonly int _defaultPageSize = 15;
    private bool _loading;
    private LoginAuditsAccessRights _accessRights = new();

    private LoginAuditsWithPaginationQuery _loginAuditsQuery { get; } = new();

    protected override async Task OnInitializedAsync()
    {
        Title = L["Login History"];
        _accessRights = await PermissionService.GetAccessRightsAsync<LoginAuditsAccessRights>();
    }

    private async Task<GridData<LoginAuditDto>> ServerReload(GridState<LoginAuditDto> state)
    {
        try
        {
            _loading = true;
            _loginAuditsQuery.OrderBy = state.SortDefinitions.FirstOrDefault()?.SortBy ?? "Id";
            _loginAuditsQuery.SortDirection = state.SortDefinitions.FirstOrDefault()?.Descending ?? true ? SortDirection.Descending.ToString() : SortDirection.Ascending.ToString();
            _loginAuditsQuery.PageNumber = state.Page + 1;
            _loginAuditsQuery.PageSize = state.PageSize;
            _loginAuditsQuery.CurrentUser = UserProfile;
            var result = await Mediator.Send(_loginAuditsQuery).ConfigureAwait(false);

            return new GridData<LoginAuditDto> { TotalItems = result.TotalItems, Items = result.Items };
        }
        finally
        {
            _loading = false;
        }
    }

    private async Task OnChangedListView(LoginAuditListView listview)
    {
        _loginAuditsQuery.ListView = listview;
        await _table.ReloadServerData();
    }

    private async Task OnChangedSuccess(bool? success)
    {
        _loginAuditsQuery.Success = success;
        await _table.ReloadServerData();
    }

    private async Task OnSearch(string text)
    {
        _loginAuditsQuery.Keyword = text;
        await _table.ReloadServerData();
    }

    private async Task OnRefresh()
    {
        _loginAuditsQuery.Keyword = string.Empty;
        _loginAuditsQuery.Success = null;
        LoginAuditCacheKey.Refresh();
        await _table.ReloadServerData();
    }

    private string GetBrowserName(string? browserInfo)
    {
        if (string.IsNullOrEmpty(browserInfo))
            return "-";

        // Simple browser detection
        if (browserInfo.Contains("Chrome"))
            return "Chrome";
        if (browserInfo.Contains("Firefox"))
            return "Firefox";
        if (browserInfo.Contains("Safari"))
            return "Safari";
        if (browserInfo.Contains("Edge"))
            return "Edge";
        
        return "Other";
    }
}
